package org.jspresso.framework.application.view.descriptor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.security.auth.Subject;

import org.jspresso.framework.application.backend.BackendControllerHolder;
import org.jspresso.framework.model.component.IComponent;
import org.jspresso.framework.model.descriptor.BasicRepeaterModelDescriptor;
import org.jspresso.framework.model.descriptor.IComponentDescriptor;
import org.jspresso.framework.view.descriptor.IViewDescriptor;
import org.jspresso.framework.view.descriptor.basic.BasicCardViewDescriptor;
import org.jspresso.framework.view.descriptor.basic.BasicEvenGridViewDescriptor;
import org.jspresso.framework.view.descriptor.basic.BasicReferencePropertyViewDescriptor;
import org.jspresso.framework.view.descriptor.basic.BasicViewDescriptor;
import org.jspresso.model.Voyage;

public class BasicRepeaterViewDescriptor extends BasicCardViewDescriptor {
  private IViewDescriptor itemViewDescriptor = null;
  private BasicEvenGridViewDescriptor basicGridViewDescriptor = null;
  
  
  public void setItemViewDescriptor(IViewDescriptor descriptor) {
    this.itemViewDescriptor = descriptor;
  }
  
  public void setBasicGridViewDescriptor(BasicEvenGridViewDescriptor descriptor) {
    this.basicGridViewDescriptor = descriptor;
  }
  
  
  
  
  @Override
  public String getCardNameForModel(Object model, Subject subject) {
    if(model != null) {
      Object colModel = ((Voyage)model).getSegments();
      int colSize = ((Collection<?>)colModel).size();
      String className = ((IComponent)model).getComponentContract().getName();
      
      return className + "#" + itemViewDescriptor.getPermId() + colSize;
    }
    return null;
  }
  
  
  @Override
  public IViewDescriptor getCardViewDescriptor(String cardName) {
    if(super.getCardViewDescriptor(cardName) == null && cardName != null) {
      
      BasicEvenGridViewDescriptor cardViewDescriptor = (BasicEvenGridViewDescriptor) basicGridViewDescriptor.clone();
      
      String repeatSizePattern = "([^0-9]*)";
      Pattern classNamePattern = Pattern.compile("([^#]*).*");
      
      int repeatSize = Integer.valueOf(cardName.replaceAll(repeatSizePattern, ""));
      String className = null;
      
      Matcher matcher = classNamePattern.matcher(cardName);
      if(matcher.find()) {
        className = matcher.group(1);
      }
      
      
      IComponentDescriptor<IComponent> itemDescriptor = (IComponentDescriptor<IComponent>) itemViewDescriptor.getModelDescriptor();
      
      
      // Create a component descriptor to be able to instanciate a component to hold the model
      BasicRepeaterModelDescriptor modelDescriptor = null;
      try {
        modelDescriptor = new BasicRepeaterModelDescriptor(BackendControllerHolder.getCurrentBackendController().getEntityFactory().getComponentDescriptor(Class.forName(className)), itemDescriptor, repeatSize);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      }
      
      //      // Create all property descriptors
      //      List<BasicReferencePropertyDescriptor> descriptors = new ArrayList<BasicReferencePropertyDescriptor>();
      //      for(int i = 0; i < repeatSize; i++) {
      //        BasicReferencePropertyDescriptor<IComponent> refDescriptor = new BasicReferencePropertyDescriptor<IComponent>();
      //        refDescriptor.setReferencedDescriptor((IComponentDescriptor<IComponent>) itemDescriptor);
      //        refDescriptor.setName("property"+i);
      //        descriptors.add(refDescriptor);
      //      }
      //      modelDescriptor.setPropertyDescriptors(descriptors);
      
      // Create all property VIEW descriptors
      List<BasicReferencePropertyViewDescriptor> viewDescriptors = new ArrayList<BasicReferencePropertyViewDescriptor>();
      for(int i = 0; i < repeatSize; i++) {
        BasicReferencePropertyViewDescriptor refDescriptor = new BasicReferencePropertyViewDescriptor();
        refDescriptor.setModelDescriptor((IComponentDescriptor<IComponent>) itemDescriptor);
        refDescriptor.setName("property"+i);
        viewDescriptors.add(refDescriptor);
      }
      
      List<IViewDescriptor> childViewDescriptors = new ArrayList<IViewDescriptor>();
      for(int i = 0; i < repeatSize; i++) {
        BasicViewDescriptor childViewDescriptor = ((BasicViewDescriptor)itemViewDescriptor).clone();
        childViewDescriptor.setName("property"+i);
        childViewDescriptors.add(childViewDescriptor);
      }
      
      
      cardViewDescriptor.setModelDescriptor(modelDescriptor);
      cardViewDescriptor.setDrivingDimensionCellCount(repeatSize);
      cardViewDescriptor.setCascadingModels(true);
      cardViewDescriptor.setCells(childViewDescriptors);
      
      putCardViewDescriptor(cardName, cardViewDescriptor);
    }
    
    return super.getCardViewDescriptor(cardName);
  }
  
  
}
